import org.devops.Constants
import org.devops.ansible
import org.devops.record
import org.devops.nodeTools


def call(Map map) {
    def ansible = new ansible()
    def nodeTools = new nodeTools()
    def record = new record()

    def execTime = nodeTools.getNowTime()
    String VALUES_URL = Constants.VALUES_URL
    String HARBOR_PROJECT = Constants.HARBOR_PROJECT
    String JENKINS_DOCKERFILES_DIR = Constants.JENKINS_DOCKERFILES_DIR
    String GIT_CREDENTIAL_ID = map.get("GIT_CREDENTIAL_ID") ?: Constants.GIT_CREDENTIAL_ID
    String VERSION = Constants.VERSION
    String BRANCH_FILTER = Constants.DEFAULT_BRANCH_FILTER
    if (map.get("P_ENV") == "prod") {
        BRANCH_FILTER = map.get("PROD_BRANCH_FILTER") ?: Constants.PROD_BRANCH_FILTER
    }

    def COMPILE_COMMAND = map.get("COMPILE_COMMAND")
    def IPS = map.get("IPS")
    def ARCHIVE = map.get("ARCHIVE")
    //运行服务器服务部署目录
    def HOST_DEPLOY_DEST = map.get("DEPLOY_DEST")
    //运行服务器运行命令
    def REMOTE_COMMAND = map.get("REMOTE_COMMAND")
    def IPS_STR = IPS.join(",")
    //jenkins服务器上建立的临时目录
    def DEPLOY_CONF_DIR = "_deploy-conf"
    //上传到ansible服务器上的压缩文件名称
    def ANSIBLE_STORE_FILE = "deploy.tar"
    def EXEC_DIR = map.get("EXEC_DIR") ?: "./"
    def NODE_VERSION = map.get("NODE_VERSION") ?: "node14.15"
    def ROLLBACK_VARIABLES_BINDINGS = "JOB_NAME=${JOB_NAME}"
    def JAVA_VERSION = map.get("JAVA_VERSION") ?: "jdk8"

//    def ROLLBACK_SCRIPT = """import groovy.json.JsonSlurper
//def conn = new URL("${PROJECT_BASE_URL}/projectInfo/last5?env=${map.P_ENV}&service=${map.P_SERVICE}&app=${map.P_APP}").openConnection()
//conn.setDoOutput(true)
//conn.connect()
//def json = new JsonSlurper().parseText(conn.inputStream.getText('UTF-8'))
//
//def selectValues = []
//for (r in json.data){
//     selectValues += ["\${r.dir}(\${r.branch} | \${r.commit} | \${r.msg})"]
//}
//
//return selectValues"""
    pipeline {
        agent any
        tools {
            jdk JAVA_VERSION
            maven 'maven'
        }
        environment {
            //必填项
            GIT_URL = map.get("GIT_URL")
            ENV = map.get("P_ENV")
            SERVICE = map.get("P_SERVICE")
            APP = map.get("P_APP")
        }
        parameters {
            extendedChoice(defaultValue: IPS_STR, description: '部署服务器', multiSelectDelimiter: ',', name: 'DEPLOY_IPS', quoteValue: false, saveJSONParameterToFile: false, type: 'PT_CHECKBOX', value: IPS_STR, visibleItemCount: 5)
            gitParameter(branch: '', branchFilter: BRANCH_FILTER, defaultValue: 'origin/master', description: '分支', name: 'BRANCH', quickFilterEnabled: false, selectedValue: 'NONE', sortMode: 'NONE', tagFilter: '*', type: 'GitParameterDefinition', useRepository: map.GIT_URL)
            choice(choices: ['deploy', 'rollback', 'init'], description: '模式', name: 'MOD')
            extendedChoice(bindings: ROLLBACK_VARIABLES_BINDINGS, groovyClasspath: '', groovyScript: Constants.ROLLBACK_SCRIPT, description: '回滚版本,只显示最近5次发布记录,倒序排列,只有在MOD为rollback时生效', multiSelectDelimiter: ',', name: 'ROLLBACK_VERSION', quoteValue: false, saveJSONParameterToFile: false, type: 'PT_SINGLE_SELECT', visibleItemCount: 5)
        }
        options {
            timestamps() // 输出构建日志打印时间信息
            timeout(time: 60, unit: 'MINUTES') // 设置构建超时时间
            buildDiscarder(logRotator(numToKeepStr: '5')) // 设置历史构建保留次数
        }
        stages {
            stage('git clone') {
                steps {
                    script {
                        String branch = "$BRANCH".replaceAll("origin/", "")
                        git branch: "${branch}", credentialsId: "${GIT_CREDENTIAL_ID}", url: "${GIT_URL}"
                    }
                }
            }
            stage('编译') {
                when {
                    environment name: 'MOD', value: 'deploy'
                }
                steps {
                    script {
                        dir(EXEC_DIR) {
                            nodejs("${NODE_VERSION}") {
                                for (command in COMPILE_COMMAND) {
                                    sh "${command}"
                                }
                            }
                        }
                    }
                }
            }
            stage('上传,部署') {
                when {
                    environment name: 'MOD', value: 'deploy'
                }
                steps {
                    script {
                        def deployIps = "${params.DEPLOY_IPS}"
                        if (deployIps.size() == 0) {
                            error "请选择要部署的服务器"
                        }


                        sh "mkdir -p ${workspace}/${DEPLOY_CONF_DIR}"
                        def processWorkspace = "${workspace}"
                        int lastIndex =  "${workspace}".lastIndexOf("@")
                        if ( lastIndex != -1 ) {
                            processWorkspace = "${workspace}".substring(0,lastIndex)
                        }
                        dir("${processWorkspace}@script/6716e897928c27f2007e6032953c1cbaccfc61bd6889d5090943c066eb4d2ba6/${JOB_NAME}") {
                            //需要上传的文件
                            if (EXEC_DIR != "./") {
                                def execDir = EXEC_DIR.replaceAll("\\./", "")
                                sh "mv ${workspace}/${execDir}/${ARCHIVE} ./"
                            } else {
                                sh "mv ${workspace}/${ARCHIVE} ./"
                            }
//                                sh "mv ${workspace}/${ARCHIVE} ./"
                            sh "find ./ -name *.sh -exec chmod +x {} \\;"
                            sh "ls -lh ./"
                            sh "tar -cf ${ANSIBLE_STORE_FILE} * --exclude=Jenkinsfile"
                            sh "mv ${ANSIBLE_STORE_FILE} ${workspace}/${DEPLOY_CONF_DIR}"
                        }

                        //通过ips判断要上传到哪
                        Map ipMap = nodeTools.processIpMap(IPS)
                        def ansibleNames = ipMap.keySet()

                        //上传到ansible服务器
                        String remoteDir = sh(returnStdout: true, script: "date +%Y%m%d%H%M%S").trim()
                        def fullPath = "/data/app_repos/${ENV}/${SERVICE}/${APP}/${remoteDir}"
                        for (ansibleName in ansibleNames) {
                            //1.在ansible服务器上建立目录
                            nodeTools.remoteExec(ansibleName, "mkdir -p ${fullPath}")
                            //2.上传文件到ansible服务器
                            nodeTools.exeSshPublisher(ansibleName, "", "${DEPLOY_CONF_DIR}/${ANSIBLE_STORE_FILE}", fullPath, true)
                            //3.在ansible服务器上执行
                            ansible.ansibleExec(ipMap, ansibleName, deployIps, ANSIBLE_STORE_FILE, HOST_DEPLOY_DEST, remoteDir, REMOTE_COMMAND)
                        }

                        //上传部署信息到project-info(记录每次部署信息)服务上,并将返回结果拼接成需要删除的node
                        record.recordProjectInfo(execTime, Constants.PROJECT_BASE_URL, remoteDir, ANSIBLE_STORE_FILE, ansibleNames)
                    }
                }
            }
            stage('回滚') {
                when {
                    environment name: 'MOD', value: 'rollback'
                }
                steps {
                    script {
                        def deployIps = "${params.DEPLOY_IPS}"
                        if (deployIps.size() == 0) {
                            error "请选择要部署的服务器"
                        }

                        def rollbackVersion = "${params.ROLLBACK_VERSION}"
                        def split = rollbackVersion.split("\\|")
                        if (split.size() == 0) {
                            error "请选择要回滚的版本"
                        }
                        def r = record.getProjectInfoByBuildNumber(Constants.PROJECT_BASE_URL,split[0])
                        //回滚指定版本
                        if (r.dir != "") {
                            Map ipMap = nodeTools.processIpMap(IPS)
                            def ansibleNames = ipMap.keySet()
                            for (ansibleName in ansibleNames) {
                                ansible.ansibleExec(ipMap, ansibleName, deployIps, ANSIBLE_STORE_FILE, HOST_DEPLOY_DEST, r.dir, REMOTE_COMMAND)
                            }
                        }
                    }
                }
            }
        }
    }
}




